﻿using System;
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows.Data;
using Caliburn.Micro;
using PocketBook.Model;
using PocketBook.ViewModels.Designs;
using PocketBook.ViewModels.Events;

namespace PocketBook.ViewModels
{
    [Export(typeof(DesignCatalogViewModel))]
    public sealed class DesignCatalogViewModel : PropertyChangedBase
    {
        public class CatalogItem
        {
            public string CategoryDisplayName { get; set; }
            public IDesign Design { get; set; }
        }

        private readonly CollectionViewSource _dataView = new CollectionViewSource();

        private readonly DesignFolder _rootFolder = new DesignFolder(String.Empty);
        private CatalogItem _selectedItem;

        public DesignCatalogViewModel()
        {
            var subFolder = _rootFolder.GetOrCreateSubFolder("Simple");
            subFolder.Add(new BlankPage());
            subFolder.Add(new CoverPage());

            subFolder = _rootFolder.GetOrCreateSubFolder("Writing Guides");
            subFolder.Add(new LinedPage());
            subFolder.Add(new GridPage { DisplayName = "Large Grid", Spacing = 32 });
            subFolder.Add(new GridPage { DisplayName = "Medium Grid", Spacing = 24 });
            subFolder.Add(new GridPage { DisplayName = "Small Grid", Spacing = 16 });
            subFolder.Add(new StoryboardPage());

            subFolder = _rootFolder.GetOrCreateSubFolder("Calendar");
            subFolder.Add(new DayPage());
            subFolder.Add(new DayPage {DisplayName = "Tomorrow", Date = DateTime.Today + TimeSpan.FromDays(1)});
            subFolder.Add(new WeekPage());
            subFolder.Add(new MonthPage());

            subFolder = _rootFolder.GetOrCreateSubFolder("Organisers");
            subFolder.Add(new ChecklistPage());

            subFolder = _rootFolder.GetOrCreateSubFolder("Games");
            subFolder.Add(new SuDoKuPage());

            var setOfTemplates = _rootFolder.SubFolders.SelectMany(folder => folder.Designs, (folder, design) => 
                new CatalogItem
                {
                    CategoryDisplayName = folder.DisplayName, 
                    Design = design
                });

            _dataView.GroupDescriptions.Add(new PropertyGroupDescription("CategoryDisplayName"));
            _dataView.Source = setOfTemplates;
        }

        public object RootFolder
        {
            get { return _rootFolder; }
        }

        public object Designs
        {
            get { return _dataView.View;  }
        }

        private void ApplyDesign(IDesign design)
        {
            Events.Publish(new NewDesignSelected((IDesign) design.Clone()));
        }

        public void ApplyDesign(CatalogItem item)
        {
            ApplyDesign(item.Design);
        }

        public bool CanApply
        {
            get { return SelectedItem != null; }
        }

        public void Apply()
        {
            ApplyDesign(SelectedItem.Design);
        }

        public CatalogItem SelectedItem
        {
            get { return _selectedItem; }
                
            set
            {
                if (value == SelectedItem) return;

                _selectedItem = value;
                NotifyOfPropertyChange(() => CanApply);
            }
        }

        [Import]
        private IEventAggregator Events { get; set; }
    }
}